package juc;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 测试 {@link java.util.concurrent.locks.Lock}
 *
 * @author hck
 */
public class TestLock {
    public static void main(String[] args) {
//        TimeUnit.SECONDS.sleep();
//        Kitchen kitchen = new Kitchen();
        LockKitchen kitchen = new LockKitchen();
        Runnable producer = () -> {
            for (int i = 0; i < 100; i++) {
                try {
                    kitchen.cook();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };


        Runnable consumer = () -> {
            for (int i = 0; i < 100; i++) {
                try {
                    kitchen.eat();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(producer);
        executorService.submit(consumer);
        executorService.shutdown();
    }
}

/**
 * 使用 {@link java.util.concurrent.locks.Lock} 实现,一个线程+1 一个线程-1
 */
class LockKitchen {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
//    private final Condition eatCondition = lock.newCondition();
    private int count = 0;

    public void cook() throws InterruptedException {
        lock.lock();
        while (count != 0) {
            //  如果count>0, 不需要加
            condition.await();
        }
        count++;
        System.out.println(Thread.currentThread().getName()+"   "+count);
        //  通知可以消费了
        condition.signalAll();
        lock.unlock();
    }

    public void eat() throws InterruptedException {
        lock.lock();
        while (count == 0) {
            //  如果为0 则等待生产
            condition.await();
        }
        count--;
        System.out.println(Thread.currentThread().getName()+"   "+count);
        //  通知消费完了可以生产了
        condition.signalAll();
        lock.unlock();
    }
}


/**
 * 使用 synchronize 实现,一个线程+1 一个线程-1
 */
class Kitchen {
    private int count = 0;

    public synchronized void cook() throws InterruptedException {
        while (count != 0) {
            //  如果count>0, 不需要加
            this.wait();
        }
        count++;
        System.out.println(Thread.currentThread().getName()+"   "+count);
        //  通知可以消费了
        this.notifyAll();
    }

    public synchronized void eat() throws InterruptedException {
        while (count == 0) {
            //  如果为0 则等待生产
            this.wait();
        }
        count--;
        System.out.println(Thread.currentThread().getName()+"   "+count);
        //  通知消费完了可以生产了
        this.notifyAll();
    }
}
